<?php
/**
 * Created by PhpStorm.
 * User: yuanxr
 * Date: 2018/6/10
 * Time: 上午8:34
 */

namespace Utility\Send;

/*************************
 * 短信发送的类
 **************************/
class ShortMSG
{
    /**
     * 设置短信内容需要的签名，会自动包含在短信内容中
     */
    private $_auth_str = "【和社区】";

    /**
     * 获取token  是json格式的  两个属性  token token_id
     */
    private $_token;

    /**
     * 设置短信需要的配置信息
     */
    private $_config = [
        /* 用户账号 */
        "cust_code" => "100164",
        /* 用户密码 */
        "cust_pwd" => "DF36OGDF6V",
        /* 服务端地址 */
        "server_address" => "http://123.58.248.206",
    ];

    /**
     * 设置服务地址后续端口和后续路由地址
     */
    private $_server_address_extend = [
        /* 普通短信 */
        "simple_msg" => ":8860/sendSms",
        /* 变量短信 */
        "variable_msg" => ":8860/sendVariantSms",
        /* 获取token */
        "get_token" => ":8860/getToken",
        /* 主动获取状态报告 */
        "get_report" => ":8860/getReport",
        /*主动获取上行消息*/
        "get_mo" => ":8860/getMO",
        /*查询帐户余额*/
        "query_account" => ":8860/QueryAccount",
    ];

    /**
     * [sendSimpleMsg 设置普通短信需要的配置信息 并且发送]
     * @param  [arr] $data [短信需要的数据]
     * @return [json]       [发送之后返回的信息]
     *
     * @param 参数实例
        'content' => '测试发送',
        'destMobiles' => 13463260681,
     */
    public function sendSimpleMsg($data)
    {
        $config = $this->_config;
        $server_address_extend = $this->_server_address_extend;
        $data = $this->checkSimpleData($data);
        /* 整理发送数据 */
        $post_data = [
            'cust_code' => $config['cust_code'],
            'sp_code' => $data['sp_code'],
            'content' => $data['content'],
            'destMobiles' => $data['destMobiles'],
            'uid' => $data['uid'],
            'need_report' =>  $data['need_report'],
            'sign' => $this->makeSign($data['content'], $config['cust_pwd']),
        ];
        $send_url = $config['server_address'].$server_address_extend['simple_msg'];
        $result = $this->sendResult($post_data, $send_url);
        return $result;
    }

    /**
     * [sendVarMsg 设置变量短信需要的配置信息 并且发送]
     * @param  [arr] $data [短信需要的数据]
     * @return [json]       [发送之后返回的信息]
     *
     * content 实例 "\${mobile}用户您好，今天\${var1}的天气，晴，温度\${var2}度，事宜外出。"
     *
     * @param 参数实例
        'content' => '测试发送${mobile},测试参数1${var1},测试参数2${var2},测试参数3${var3},测试参数4${var4},测试参数5${var5}',
        'params' => [
            [
                'mobile' => 13463260681,
                'vars' => ['一','二','三','四','五'],
            ],
            [
                'mobile' => 17732451230,
                'vars' => ['一','二','三','四','五'],
            ],
        ]
     */
    public function sendVarMsg($data)
    {
        $config = $this->_config;
        $server_address_extend = $this->_server_address_extend;
        $data = $this->checkVarData($data);
        /* 整理发送数据 */
        $post_data = [
            'cust_code' => $config['cust_code'],
            'sp_code' => $data['sp_code'],
            'content' => $data['content'],
            'params' => $data['params'],
            'sign' => $this->makeSign($data['content'], $config['cust_pwd']),
        ];
        $send_url = $config['server_address'].$server_address_extend['variable_msg'];
        $result = $this->sendResult($post_data, $send_url);
        return $result;
    }

    /**
     * [checkSimpleData 转化检测提供的普通短信数据]
     * @param  [arr] $data [description]
     * @return [arr]       [整理后的发送数据]
     */
    private function checkSimpleData($data)
    {
        $data = $this->checkGenData($data);
        /* 检查转化发送号码 */
        $destMobiles = $data['destMobiles'];
        if (isset($destMobiles)) {
            if (is_array($destMobiles)) {
                $destMobiles = implode(",", $destMobiles);
            }
            $data['destMobiles'] = $destMobiles;
        } else {
            echo "checkSimpleData-缺少需要发送短信的号码";
            exit();
        }
        /* 检查转化业务标识号码 */
        if (isset($data['uid'])) {
            if (!preg_match_all('/^[0-9]+$/', $data['uid'])) {
                echo "checkSimpleData-业务标识必须为数字";
                exit();
            }
            if (strlen($data['uid'])>20) {
                echo "checkSimpleData-业务标识已经超过20位，不符合短信商提供的要求";
                exit();
            }
        } else {
            $data['uid'] = "";
        }
        /* 检查转化是否需要发送报告 */
        if (isset($data['need_report'])) {
            if ($data['need_report'] != "yes" && $data['need_report'] != "no") {
                echo "checkSimpleData-need_report填写必须为yes或者no";
                exit();
            }
        } else {
            $data['need_report'] = "yes";
        }
        return $data;
    }

    /**
     * [checkSimpleData 转化检测提供的变量短信数据]
     * @param  [arr] $data [description]
     * @return [arr]       [整理后的发送数据]
     */
    private function checkVarData($data)
    {
        $data = $this->checkGenData($data);
        $var_count = substr_count($data['content'], "$")-1;
        if (isset($data['params'])) {
            if (!is_array(reset($data['params']))) {
                $data['params'] = [$data['params']];
            }
            foreach ($data['params'] as $key => $params) {
                if (!array_key_exists('mobile', $params)) {
                    echo "checkVarData-params缺少 mobile 参数";
                    exit();
                }
                if (array_key_exists('vars', $params)) {
                    if (count($params['vars'])!=$var_count) {
                        echo "checkVarData-params缺少 ['params']['vars'] 中参数数量不符";
                        exit();
                    }
                } else {
                    echo "checkVarData-params缺少 vars 参数";
                    exit();
                }
            }
        } else {
            echo "checkVarData-缺少params参数";
            exit();
        }
        return $data;
    }


    /**
     * [checkSimpleData 转化检测提供的通用短信数据]
     * @param  [arr] $data [description]
     * @return [arr]       [整理后的发送数据]
     * 注意：只是给普通数据和变量数据检查提供
     */
    private function checkGenData($data)
    {
        /* 检查转化长号码 */
        $data['sp_code'] = isset($data['sp_code'])? (int)$data['sp_code'] : "";
        /* 检查转化内容 */
        if (!isset($data['content'])) {
            echo "checkGenData-短信内容不能为空!!";
            exit();
        } else {
            $data['content'] = $this->_auth_str.$data['content'];
        }
        return $data;
    }

    /**
     * [getReport 获取状态报告信息]
     * @return [json] [数据报告]  短信商提供4天以内的报告  返回多条
     */
    public function getReport()
    {
        $server_address_extend = $this->_server_address_extend;
        $result = $this->getGen($server_address_extend['get_report']);
        return $result;
    }

    /**
     * [getMO 获取上行信息  发送的短信的相关信息]
     * @return [json] [时间内容等]
     */
    public function getMO()
    {
        $server_address_extend = $this->_server_address_extend;
        $result = $this->getGen($server_address_extend['get_mo']);
        return $result;
    }

    /**
     * [queryAccount 查询账户余额]
     * @return [json] [账户相关余额信息]
     */
    public function queryAccount()
    {
        $server_address_extend = $this->_server_address_extend;
        $result = $this->getGen($server_address_extend['query_account']);
        return $result;
    }

    /**
     * [getGen 获取报告，上行信息，余额等通用函数提供共有方法]
     * @param  [str] $server_address_extend [后续地址]
     * @return [json]                        [返回值]
     */
    private function getGen($address_extend)
    {
        $this->getTokenData();
        $config = $this->_config;
        $post_data = [
            'cust_code' => $config['cust_code'],
            'token_id' => $this->getTokenId(),
            'sign' => $this->makeSign($this->getToken(), $config['cust_pwd']),
        ];
        $send_url = $config['server_address'].$address_extend;
        $result = $this->sendResult($post_data, $send_url);
        return $result;
    }

    /**
     * [getToken 获取token 用于查询报告和查询余额等]
     * @return [str] [获取的token数据]
     */
    private function getToken()
    {
        return $result = $this->_token['token'];
    }
    /**
     * [getTokenId 获取token 用于查询报告和查询余额等]
     * @return [str] [获取的token数据]
     */
    private function getTokenId()
    {
        return $result = $this->_token['token_id'];
    }

    /**
     * [getTokenData 获取token数据 用于查询报告和查询余额等  短信商返回实例 "token":"szoh9hm36qv7zbrf4a6r","token_id":"10loh1c9ac"]
     * @return [str] [获取的token数据]
     */
    private function getTokenData()
    {
        $config = $this->_config;
        $server_address_extend = $this->_server_address_extend;
        $post_data = [
            'cust_code' => $config['cust_code']
        ];
        $send_url = $config['server_address'].$server_address_extend['get_token'];
        $result = $this->sendResult($post_data, $send_url);
        $result = json_decode($result, true);
        $this->_token = $result;
    }

    /**
     * [makeSign description]
     * @param  [str] $var1 [参数一]
     * @param  [str] $var2 [参数二]
     * @return [str]       [返回的sign]
     */
    private function makeSign($var1, $var2)
    {
        if (isset($var2) && isset($var1)) {
            $sign = $var1.$var2;
            return md5($sign);
        } else {
            echo "makeSign-缺少生成sign的参数";
            exit();
        }
    }

    /**
     * [sendResult 通用的数据数据返回方法]
     * @param  [arr] $post_data             [提交的数据]
     * @param  [str] $server_address_extend [网站的后续扩展部分]
     * @return [json]                        [返回的结果]
     */
    private function sendResult($post_data, $send_url)
    {
        $config = $this->_config;
        $ch = $this->sendHttp();
        $post_data = json_encode($post_data);
        $send_url = $send_url;
        $result = $this->sendMsg($ch, $post_data, $send_url);
        return $result;
    }

    /**
     * [sendMsg 发送数据]
     * @param  [obj] $ch       [curl]
     * @param  [json] $data     [提交的数据]
     * @param  [str] $send_url [提交的网址]
     * @return [josn]           [返回的数据]
     */
    private function sendMsg($ch, $data, $send_url)
    {
        curl_setopt($ch, CURLOPT_URL, $send_url);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        return curl_exec($ch);
    }


    /**
     * [sendHttp 设置模拟发送环境]
     * @return [obj] [curl实例化对象]
     */
    private function sendHttp()
    {
        try {
            $ch = curl_init();
            /* 设置验证方式 */
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json','charset=utf-8'));
            /* 设置返回结果为流 */
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            /* 设置超时时间*/
            curl_setopt($ch, CURLOPT_TIMEOUT, 300);
            /* 设置通信方式 */
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            return $ch;
        } catch (Exception $e) {
            echo $e->getMessage();
            exit;
        }
    }
}
